#include "MainWindow.h"
#include "AssetAdder.h"
#include "AssetDelegate.h"
#include "ResultView.h"
#include "QuestionItem.h"
#include "LinkItem.h"

namespace Xps
{

	MainWindow::MainWindow() : QMainWindow()
	{		
		setWindowTitle("New Project");
		am = new XpsAssets::AssetManager();
		assetpool = new Xps::AssetPool(am);
		treeview = new Xps::TreeView(am);
		tb1 = new QToolBar("Main");
		tb2 = new QToolBar("Graph Toolset");
		tab = new QTabWidget();
		results = new Xps::ResultView(am);
		tb3 = assetpool->tb;

		tb1->setIconSize(QSize(30,30));
		tb2->setIconSize(QSize(30,30));
		tb3->setIconSize(QSize(30,30));

		//tb1->setEnabled(false);
		setupActions();

		tb1->addActions(actions);
		tb2->addActions(treeview->actions);

		addDockWidget("Asset Pool", assetpool);
		tab->addTab(treeview, "Graph");
		tab->addTab(results, "Results");

		setStatusBar(new QStatusBar(this));
		setCentralWidget(tab);
		addToolBar(tb1);
		addToolBar(tb2);
		addToolBar(tb3);

		connect(assetpool, SIGNAL(sAddToTree(int)), treeview, SLOT(addQuestionItem(int)));
		connect(am, SIGNAL(sAssetsLoaded()), this, SLOT(cleanUp()));
		connect(tab, SIGNAL(currentChanged(int)), this, SLOT(switchWorkspace(int)));
	}

	void MainWindow::cleanUp()
	{
		assetpool->tm->clear();
		results->clear();
		am->cleanUp();
		treeview->cleanUp();
	}

	void MainWindow::switchWorkspace(int ws)
	{
		if (ws == 1)
		{
			tb2->setDisabled(true);
			treeview->props->hide();
		}
		else
		{
			tb2->setDisabled(false);
			treeview->props->show();
		}
	}

	void MainWindow::setupActions()
	{
		QAction* action;
		
		action = new QAction(QIcon(":/rs/images/new.png"),"New",this);
		connect(action, SIGNAL(triggered()), this, SLOT(newProject()));
		actions.append(action);
		
		action = new QAction(QIcon(":/rs/images/open.png"), "Open", this);
		connect(action, SIGNAL(triggered()), this, SLOT(openProject()));
		actions.append(action);
		
		action = new QAction(QIcon(":/rs/images/save.png"), "Save",this);
		connect(action, SIGNAL(triggered()), this, SLOT(saveProject()));
		actions.append(action);
		
		action = new QAction(QIcon(":/rs/images/play.png"), "Run",this);
		connect(action, SIGNAL(triggered()), this, SLOT(runProject()));
		actions.append(action);

		connect(treeview->aCreateQuestionItem, SIGNAL(triggered()), this, SLOT(addQuestionItem()));
		connect(treeview->props->cd->add, SIGNAL(clicked()), this, SLOT(addConstraintAttribute()));
	}

	void MainWindow::runProject()
	{
		QString program = "XPS-Viewer.exe";
		QStringList arguments;

		if (!QFile(program).exists())
		{
			QMessageBox::critical(this, "Error", "Could not locate viewer application.");
			return;
		}

		if (am->document() == "")
			return;

		arguments << "-load" << am->document();

		QProcess* myProcess = new QProcess();
		myProcess->start(program, arguments); 
	}

	void MainWindow::newProject()
	{
		cleanUp();
		am->setDocument("");
		setWindowTitle("New Project");
	}

	void MainWindow::saveProject()
	{
		//if (am->document() == "")
			saveAsProject();
		/*else
			save(am->document());*/
	}

	void MainWindow::saveAsProject()
	{
		QString filename;

		filename = QFileDialog::getSaveFileName(this, tr("Save Project"), QDir::currentPath(), tr("XPS Project File (*.xml)")); 
		
		if (filename == "")
			return; // canceled

		save(filename);
	}

	void MainWindow::save(QString filename)
	{
		am->save(filename,constructTree());
		setWindowTitle(am->document());
	}

	TreeNodeList MainWindow::constructTree()
	{
		// generate tree for saving
		QList<XpsAssets::TreeNode*> tree;
		QMap<int, Item*> tmp;

		// store nonlink items
		QList<QGraphicsItem*> items = treeview->scene()->items();

		for (int i = 0; i < items.count(); i++)
		{
			XpsAssets::TreeNode* tn = NULL;
			Item* item = (Item*) items.at(i);
			int refid = -1;
			
			// skip link items
			if (item->getType() == XpsAssets::TreeNode::LINK)
				continue;

			// if item is qitem store question reference
			if (item->getType() == XpsAssets::TreeNode::QUESTION)
				refid = ((Tree::QuestionItem*)item)->questionid;
			
			// if item is constraint create specific node
			if (item->getType() == XpsAssets::TreeNode::CONSTRAINT)
			{
				tn = new XpsAssets::ConstraintNode(i, item->pos().toPoint());
				((XpsAssets::ConstraintNode*)tn)->attributes = *((ConstraintItem*)item)->attributes();
			}
			// else default node
			else
				tn = new XpsAssets::TreeNode(i, item->getType(), item->pos().toPoint(), refid);
			
			tree.append(tn);
			
			// store items with id for link references
			tmp.insert(i, item);
		}

		// store all links
		QList<LinkItem*> links = treeview->links;

		for (int i = 0; i < links.count(); i++)
		{
			XpsAssets::TreeNode* tn = NULL;
			LinkItem* item = (LinkItem*) links.at(i);
			
			tn = new XpsAssets::TreeNode(tmp.count()+i, XpsAssets::TreeNode::LINK, item->pos().toPoint(), -1);
			tn->_parent = tmp.key(item->parent());
			tn->_child = tmp.key(item->child());
			
			if (item->parent()->getType() == XpsAssets::TreeNode::CONSTRAINT)
			{
				if (item->child() == ((ConstraintItem*) item->parent())->trueNode())
					tn->_mode = 1;
				else
					tn->_mode = 2;
			}
			else
				tn->_mode = 0;

			tree.append(tn);
		}

		return tree;
	}

	void MainWindow::openProject()
	{
		QString filename;

		filename = QFileDialog::getOpenFileName(this, tr("Open Project"), QDir::currentPath(), tr("XPS Project File (*.xml)")); 
		
		if (filename == "")
			return; // canceled

		am->load(filename);

		if (am->document() != "")
			setWindowTitle(am->document());
		else
			setWindowTitle("New Project");
	}

	void MainWindow::addDockWidget(QString name, QWidget* widget)
	{
		dockwidgets.insert(name, new QDockWidget(name, this));
		dockwidgets[name]->setWidget(widget);
		dockwidgets[name]->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
		QMainWindow::addDockWidget(Qt::RightDockWidgetArea, dockwidgets[name]);
	}


	void MainWindow::addConstraintAttribute()
	{
		AssetSelector* as = new AssetSelector(this, "Select Attribute", ":/rs/images/select.png", assetpool->tm->attributesModel);

		if (QDialog::Accepted != as->exec())
			return;

		int id = as->selectedAsset();
			
		if (id == -1)
			return;
			
		treeview->props->cd->addAttribute(id);
	}

	void MainWindow::addQuestionItem()
	{
		AssetSelector* as = new AssetSelector(assetpool, "Select Question", ":/rs/images/select.png", assetpool->tm->qm);
		
			
		if (QDialog::Accepted == as->exec())
		{
		
			int id = as->selectedAsset();
			
			if (id == -1)
				return;

			treeview->addQuestionItem(id);
		}
	}
}